﻿using System;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using TestByWire.Factories.StubbingStrategies;

namespace TestByWire.Test.Factories.StubbingStrategies
{
	[TestClass]
	public class ValueTypeAndStringArrayStrategyTest
	{
		private ValueTypeAndStringArrayStrategy _valueTypeArrayStrategy;

		[TestInitialize]
		public void PerTestSetup()
		{
			_valueTypeArrayStrategy = new ValueTypeAndStringArrayStrategy();
		}

		[TestMethod]
		public void CanHandleTypeMustReturnTrueIfTypeIsArrayAndElementTypeIsValueType()
		{
			var instance = new[] { 1, 2 };

			bool canHandle = _valueTypeArrayStrategy.CanHandleType(instance.GetType(), null);

			Assert.IsTrue(canHandle);
		}

		[TestMethod]
		public void CanHandleTypeMustReturnTrueIfTypeIsArrayAndElementTypeIsString()
		{
			var instance = new[] { "A", "B" };

			bool canHandle = _valueTypeArrayStrategy.CanHandleType(instance.GetType(), null);

			Assert.IsTrue(canHandle);
		}

		[TestMethod]
		public void CanHandleTypeMustReturnFalseIfTypeIsArrayAndElementTypeIsRefType()
		{
			var instance = new[] { new object() };

			bool canHandle = _valueTypeArrayStrategy.CanHandleType(instance.GetType(), null);

			Assert.IsFalse(canHandle);
		}

		[TestMethod]
		public void CanHandleTypeMustThrowIfTypeIsNull()
		{
			var exception = AssertEx.Throws<ArgumentNullException>(() => _valueTypeArrayStrategy.CanHandleType(null, null));

			Assert.AreEqual("type", exception.ParamName);
		}

		[TestMethod]
		public void CompletesBuildMustReturnFalse()
		{
			Assert.IsFalse(_valueTypeArrayStrategy.CompletesBuild);
		}

		[TestMethod]
		public void TryCreateInstanceMustReturnZeroLengthStringIfTypeIsStringArray()
		{
			var stringArrayType = (new[] { "A" }).GetType();

			var instance = _valueTypeArrayStrategy.CreateInstance(stringArrayType, null);

			Assert.IsTrue(instance.GetType().IsArray && instance.GetType().GetElementType() == typeof(string));
		}

		[TestMethod]
		public void TryCreateInstanceMustReturnZeroLengthIntArrayIfTypeIsIntArray()
		{
			var stringArrayType = (new[] { 1, 2 }).GetType();

			var instance = _valueTypeArrayStrategy.CreateInstance(stringArrayType, null);

			Assert.IsTrue(instance.GetType().IsArray && instance.GetType().GetElementType() == typeof(int));
		}
	}
}
